using System;
using System.Collections.Generic;
using System.Linq.Expressions;
using Microsoft.EntityFrameworkCore.Query;
using Microsoft.EntityFrameworkCore.Query.SqlExpressions;
using Microsoft.EntityFrameworkCore.Storage;

namespace Microsoft.EntityFrameworkCore.Dm.Query.Internal;

public class DmSqlTranslatingExpressionVisitor : RelationalSqlTranslatingExpressionVisitor
{
	private static readonly HashSet<string> _dateTimeDataTypes = new HashSet<string> { "time", "date", "datetime", "datetime2", "datetimeoffset" };

	private static readonly HashSet<ExpressionType> _arithmeticOperatorTypes = new HashSet<ExpressionType>
	{
		ExpressionType.Add,
		ExpressionType.Subtract,
		ExpressionType.Multiply,
		ExpressionType.Divide,
		ExpressionType.Modulo
	};

	public DmSqlTranslatingExpressionVisitor(RelationalSqlTranslatingExpressionVisitorDependencies dependencies, QueryCompilationContext queryCompilationContext, QueryableMethodTranslatingExpressionVisitor queryableMethodTranslatingExpressionVisitor)
		: base(dependencies, queryCompilationContext, queryableMethodTranslatingExpressionVisitor)
	{
	}

	protected override Expression VisitBinary(BinaryExpression binaryExpression)
	{
		if (binaryExpression.NodeType == ExpressionType.Subtract)
		{
			SqlExpression sqlExpression = this.Visit(binaryExpression.Left) as SqlExpression;
			if (sqlExpression != null)
			{
				SqlExpression sqlExpression2 = this.Visit(binaryExpression.Right) as SqlExpression;
				if (sqlExpression2 != null && sqlExpression.Type == typeof(TimeOnly) && sqlExpression2.Type == typeof(TimeOnly))
				{
					return null;
				}
			}
		}
		return base.VisitBinary(binaryExpression);
	}

	public override SqlExpression TranslateLongCount(SqlExpression expression = null)
	{
		if (expression != null)
		{
			return this.Dependencies.SqlExpressionFactory.ApplyDefaultTypeMapping(this.Dependencies.SqlExpressionFactory.Function("COUNT", new SqlExpression[] { expression }, false, new bool[1], typeof(long), null));
		}
		return this.Dependencies.SqlExpressionFactory.ApplyDefaultTypeMapping(this.Dependencies.SqlExpressionFactory.Function("COUNT", new SqlFragmentExpression[] { this.Dependencies.SqlExpressionFactory.Fragment("*") }, false, new bool[1], typeof(long), null));



	}

	private static string GetProviderType(SqlExpression expression)
	{
		RelationalTypeMapping typeMapping = expression.TypeMapping;
		if (typeMapping == null)
		{
			return null;
		}
		return typeMapping.StoreType;
	}
}
